/**
 * @file user_gpio.c
 * @brief GPIO驱动实现
 * 
 * 包含GPIO初始化、LED控制和中断处理等功能。
 */

#include "user_gpio.h"
#include "user_config.h"
#include "log_utils.h"
#include "driver/gpio.h"
#include "sdkconfig.h"

static const char *TAG = "user_gpio";

// LED控制状态
static bool led_state = false;

/**
 * @brief 初始化GPIO
 * 
 * 根据配置初始化所有需要的GPIO引脚。
 */
void user_gpio_init(void)
{
    // 配置GPIO为输入输出模式
    gpio_config_t io_conf = {
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE
    };
    
    // 初始化LED GPIO（如果已定义）
#if defined(CONFIG_LED_GPIO)
    io_conf.pin_bit_mask = (1ULL << CONFIG_LED_GPIO);
    ESP_ERROR_CHECK(gpio_config(&io_conf));
    ESP_LOGI(TAG, "LED GPIO %d 初始化完成", CONFIG_LED_GPIO);
#endif

    // 初始化DHT11 GPIO为输出开漏模式（如果已定义）
#if defined(CONFIG_DHT11_GPIO)
    io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD;
    io_conf.pin_bit_mask = (1ULL << CONFIG_DHT11_GPIO);
    ESP_ERROR_CHECK(gpio_config(&io_conf));
    ESP_LOGI(TAG, "DHT11 GPIO %d 初始化完成", CONFIG_DHT11_GPIO);
#endif
}

/**
 * @brief 初始化LED
 * 
 * 初始化LED控制功能。
 */
void user_gpio_led_init(void)
{
#if defined(CONFIG_LED_GPIO)
    // 设置LED初始状态为关闭
    gpio_set_level(CONFIG_LED_GPIO, 0);
    ESP_LOGI(TAG, "LED初始化完成，初始状态为关闭");
#endif
}

/**
 * @brief 设置LED状态
 * 
 * @param state LED状态（true为开启，false为关闭）
 */
void user_gpio_set_led(bool state)
{
#if defined(CONFIG_LED_GPIO)
    gpio_set_level(CONFIG_LED_GPIO, state ? 1 : 0);
    led_state = state;
    ESP_LOGD(TAG, "LED状态设置为: %s", state ? "开启" : "关闭");
#endif
}

/**
 * @brief 切换LED状态
 * 
 * 切换LED的开关状态。
 */
void user_gpio_toggle_led(void)
{
#if defined(CONFIG_LED_GPIO)
    led_state = !led_state;
    gpio_set_level(CONFIG_LED_GPIO, led_state ? 1 : 0);
    ESP_LOGD(TAG, "LED状态切换为: %s", led_state ? "开启" : "关闭");
#endif
}

/**
 * @brief 获取LED状态
 * 
 * @return bool LED当前状态
 */
bool user_gpio_get_led_state(void)
{
#if defined(CONFIG_LED_GPIO)
    return led_state;
#else
    return false;
#endif
}

/**
 * @brief 设置GPIO电平
 * 
 * @param gpio_num GPIO编号
 * @param level 电平状态（0或1）
 */
void user_gpio_set_level(gpio_num_t gpio_num, uint32_t level)
{
    gpio_set_level(gpio_num, level);
    ESP_LOGD(TAG, "GPIO %d 设置为 %d", gpio_num, level);
}

/**
 * @brief 读取GPIO电平
 * 
 * @param gpio_num GPIO编号
 * @return int GPIO电平状态（0或1）
 */
int user_gpio_get_level(gpio_num_t gpio_num)
{
    int level = gpio_get_level(gpio_num);
    ESP_LOGD(TAG, "GPIO %d 读取值为 %d", gpio_num, level);
    return level;
}